﻿using System;
using CzfSDK;
using MySql.Data.MySqlClient;
using System.Collections;
using System.Collections.Generic;

namespace Server
{
	public static class MailManager
	{
		const string SEND_MAIL_NO_READ = "RefreshMailCount"; // 推送玩家未读邮件的接口
		const int MAX_DAY = 7; // 邮件最多保存几天

		// 获取玩家的邮件列表
		public static List<Hashtable> GetAllMail(int userId)
		{
			return GetAll (userId);
		}

		// 推送玩家的未读邮件数量
		public static void CheckNoReadCount(int userId)
		{
			var user = User.Get (userId);
			if (user != null && user.client != null) {
				int count = GetNoRead (userId);
				CzfNetManager.current.Call (user.client, SEND_MAIL_NO_READ, null, 0, count);
			}
		}

		// 将邮件标记已读
		public static void SetReadType(int userId, int mailId)
		{
			UpdateReadType (mailId, 1);
			// 推送
			CheckNoReadCount(userId);
		}


		// 领取邮件附件
		public static string GetMailPrize(int userId, int mailId)
		{
			var mail = Get (mailId);
			if (mail.GetVal<int> ("userid") != userId) {
				throw new CzfProtoException (Constants.ERR3, "错误的邮件id");
			}

			if (mail.GetVal<int> ("readtype") == 2) {
				throw new CzfProtoException (Constants.ERR3, "已经领取过了");
			}

			var prize = mail.GetVal<string> ("appendix");
			if (prize == null || prize == "") {
				throw new CzfProtoException (Constants.ERR3, "该邮件没有附件");
			}

			var title = mail.GetVal<string> ("title");

			UpdateReadType (mailId, 2);
			BagManager.AddItem (prize, userId, "邮件领取", title);

			return "ok";
		}

		// 删除邮件
		public static void DelMail(int userId, int mailId)
		{
			Delete (mailId);
		}

		/// <summary>
		/// 给玩家发送一封邮件
		/// </summary>
		/// <param name="userId">User identifier.</param>
		/// <param name="category">Category.</param>
		/// <param name="title">Title.</param>
		/// <param name="content">Content.</param>
		/// <param name="prize">附件内容</param>
		/// <param name="time">创建时间</param>
		/// <param name="templateId">模板id,模板id与全服邮件的id对应</param>
		public static void SendMail(int userId, int category, string title, string content, string prize, DateTime time, int templateId, bool check = true)
		{
			Add (userId, category, title, content, prize, time, templateId);
			if(check)
				CheckNoReadCount (userId);
		}

		// 邮件每日检测,发送最新的全服邮件,删除过期的邮件
		public static void DayCheck(int userId)
		{
			var allMail = GetAllMail (userId);
			var allTemp = GetAllTemp ();

			var hasTemps = new HashSet<int> ();

			// 删除过期的邮件
			for (int i = 0; i < allMail.Count; i++) {
				var tempId = allMail [i].GetVal<int> ("templateid");
				var createTime = allMail [i].GetVal<DateTime> ("createtime");
				var mailId = allMail [i].GetVal<int> ("id");
				var prize = allMail [i].GetVal<string> ("appendix");

				hasTemps.Add (tempId);

				if ((createTime - DateTime.Now).TotalDays > MAX_DAY) {
					if (prize != null && prize != "") {
						GetMailPrize (userId, mailId);
					}
					DelMail (userId, mailId);
				}
			}

			// 补发全服邮件
			foreach (var temp in allTemp) {
				var tempId = temp.GetVal<int> ("id");
				if (!hasTemps.Contains (tempId)) {
					var category = temp.GetVal<int> ("category");
					var title = temp.GetVal<string> ("title");
					var content = temp.GetVal<string> ("content");
					var prize = temp.GetVal<string> ("appendix");
					var time = temp.GetVal<DateTime> ("createtime");
					SendMail (userId, category, title, content, prize, time, tempId, false);
				}
			}

			// 推送
			CheckNoReadCount(userId);
		}

		#region DB
		// 获取所有的全服邮件
		public static List<Hashtable> GetAllTemp()
		{
			var start = DateTime.Now.AddDays (-MAX_DAY);
			var end = DateTime.Now;

			var sql = "select * from mailtemplate where createtime > @start and createtime < @end";

			var dt = MysqlPool.current.ExecDataTable (sql,
				new MySqlParameter ("@start", start),
				new MySqlParameter ("@end", end)
			);
			if (dt == null)
				return null;
			else
				return dt.ToList ();
		}

		// 删除指定id的邮件
		private static int Delete(int mailId)
		{
			var sql = "delete from mail where id = @id";
			return MysqlPool.current.ExecuteNonQuery (sql, 
				new MySqlParameter ("@id", mailId)
			);
		}

		// 获取指定id的邮件
		public static Hashtable Get(int mailId)
		{
			var sql = "select * from mail where id = @id";
			var dr = MysqlPool.current.ExecDataRow (sql,
				new MySqlParameter ("@id", mailId)
			);
			if (dr == null)
				return null;
			else
				return dr.ToHashtable ();
		}

		// 修改邮件已读标识
		public static void UpdateReadType(int id, int readType)
		{
			var sql = "update mail set readtype=@readtype where id=@id";
			MysqlPool.current.ExecuteNonQuery (sql,
				new MySqlParameter ("@id", id),
				new MySqlParameter ("@readtype", readType)
			);
		}

		// 获取玩家的邮件列表
		public static List<Hashtable> GetAll(int userId)
		{
			var sql = "select * from mail where userid = @userid";
			var dt = MysqlPool.current.ExecDataTable (sql,
				new MySqlParameter ("@userid", userId)
			);
			if (dt == null)
				return null;
			else
				return dt.ToList ();
		}

		// 获取玩家的未读邮件数量
		private static int GetNoRead(int userId)
		{
			var sql = "select count(*) from mail where userid = @userid and readtype = 0";
			return MysqlPool.current.ExecInt (sql,
				new MySqlParameter ("@userid", userId)
			);
		}

		// 创建一封邮件
		private static int Add(int userId, int category, string title, string content, string prize, DateTime time, int templateId)
		{
			var sql = "insert into mail(userid, title, content, appendix, readtype, category, createtime, templateid) values(@userid, @title, @content, @appendix, 0, @category, @createtime, @templateid)";
			return MysqlPool.current.ExecuteNonQuery (sql, 
				new MySqlParameter ("@userid", userId),
				new MySqlParameter ("@title", title),
				new MySqlParameter ("@content", content),
				new MySqlParameter ("@appendix", prize),
				new MySqlParameter ("@category", category),
				new MySqlParameter ("@createtime", time),
				new MySqlParameter ("@templateid", templateId)
			);
		}
		#endregion
	}
}

